package com.example.personalizededucationsystem.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

// REMOVED: @Data, @Builder, @NoArgsConstructor, @AllArgsConstructor
@Setter
@Entity
@Table(name = "users")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User implements UserDetails {

    @Getter
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long userId;

    @Column(nullable = false, unique = true)
    private String username;

    @Getter
    @Column(nullable = false)
    private String nickname;

    @Column(nullable = false)
    private String password;

    @Getter
    @Column(nullable = false)
    private String email;

    @Getter
    @Setter
    @Column
    private String avatar;

    @Getter
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private Role role;

    @Getter
    @Enumerated(EnumType.STRING)
    private Subscription subscription;

    @Getter
    @Column(nullable = false, updatable = false)
    private Instant createdAt;

    @Getter
    private boolean isActive = true;

    @Getter
    @Setter
    private String backgroundUrl;

    // ADDED: No-argument constructor (required by JPA)
    public User() {
    }

    @PrePersist
    protected void onCreate() {
        createdAt = Instant.now();
    }

    // --- Spring Security UserDetails interface implementation ---

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of(new SimpleGrantedAuthority("ROLE_" + role.name()));
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return this.isActive;
    }

    // --- Manual equals, hashCode, and toString ---

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(userId, user.userId) && Objects.equals(username, user.username);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userId, username);
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", username='" + username + '\'' +
                ", email='" + email + '\'' +
                ", role=" + role +
                '}';
    }

    // --- Enum definitions ---
    public enum Role {
        STUDENT,
        TEACHER,
        ADMIN
    }

    public enum Subscription {
        NORMAL,
        PREMIUM
    }
}